﻿#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

//题1
void GetMemory1(char* p)
{
	p = (char*)malloc(100);
}

void test1()
{
	char* str = NULL;
	GetMemory1(str);
	strcpy(str, "hello world");
	printf(str);
}
//1.调用GetMemory函数的时候，str的传参为值传递，p是str的临时拷贝，
//所以在GetMemory函数内部讲动态开辟的内存空间的地址存放在p中的时候，
//不会影响到str，所以GetMemory函数返回之后，str中依然是NULL指针。
//strcpy函数调用失败，原因是对空指针的解引用。
//2.GetMemory函数内malloc的空间没有机会释放，造成了内存泄漏。

//题1修改方案1
char* GetMemory1_r1()
{
	char* p = (char*)malloc(100);
	return p;
}

void test1_r1()
{
	char* str = GetMemory1_r1();
	strcpy(str, "hello world");
	printf(str);
	free(str);
	str = NULL;
}

//题1修改方案2
void GetMemory1_r2(char** p)
{
	*p = (char*)malloc(100);
}

void test1_r2()
{
	char* str = NULL;
	GetMemory1_r2(&str);
	strcpy(str, "hello world");
	printf(str);
	free(str);
	str = NULL;
}

//题2
char* GetMemory2()
{
	char p[] = "hello world";
	return p;
}

void test2(void)
{
	char* str = NULL;
	str = GetMemory2();
	printf(str);
}
//返回栈空间地址的问题：
//GetMemory函数内部创建的数组是临时的，虽然返回了数组的其起始地址给str，
//但是数组的内存出了GetMemory函数就被回收了，而str依然保存着数组的起始地址，
//这时如果使用str，str就是野指针。

//题3
void GetMemory3(char** p, int num)
{
	*p = (char*)malloc(num);
}

void test3()
{
	char* str = NULL;
	GetMemory3(&str, 100);
	strcpy(str, "hello");
	printf(str);
}
//没有释放malloc的空间

//题3修改方案
void GetMemory3_r1(char** p, int num)
{
	*p = (char*)malloc(num);
}

void test3_r1()
{
	char* str = NULL;
	GetMemory3_r1(&str, 100);
	strcpy(str, "hello");
	printf(str);
	//释放
	free(str);
	str = NULL;
}

//题4
void test4()
{
	char* str = (char*)malloc(100);
	strcpy(str, "hello");
	free(str);
	if (str != NULL)
	{
		strcpy(str, "world");
		printf(str);
	}
}
//free后没有置空，str为野指针

//题4修改方案
void test4_r()
{
	char* str = (char*)malloc(100);
	strcpy(str, "hello");
	free(str);
	str = NULL;
	if (str != NULL)
	{
		strcpy(str, "world");
		printf(str);
	}
}

int main()
{
	//test1();
	test1_r1();
	printf("\n");
	test1_r2();
	printf("\n");
	//test2();
	//test3();
	test3_r1();
	//test4();
	test4_r();
	return 0;
}